﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Numerics;
using System.Text;
using System.Threading;

namespace MainPaper
{
    class Program
    {
        static void Main()
        {
            Thread.CurrentThread.Priority = ThreadPriority.Highest;
            for (int j = 0; j < 7; j++)
            {
                int bitlength = 64 + 64 * j;
                int numberOfUsers = 10;
                int numberOfRuns = 10;
                long mainPaperTime = 0;
                long paper17Time = 0;
                long paper18Time = 0;
                for (int i = 0; i < numberOfRuns; i++)
                {
                    mainPaperTime += MainPaper.Execute(numberOfUsers, bitlength, true);
                    paper17Time += Paper17.Execute(numberOfUsers, bitlength, true);
                    paper18Time += Paper18.Execute(numberOfUsers, bitlength, true);
                }
                Console.WriteLine("# bitlength:{0}", bitlength); 
                Console.WriteLine("{0}\n{1}\n{2}", mainPaperTime / numberOfRuns, paper17Time / numberOfRuns, paper18Time / numberOfRuns);
                Console.WriteLine();
            }
            Console.ReadKey();

            //var mask = 0xFF >> (8 * 5 - x);

            // BigInteger q = 128;
            // var ba = q.ToByteArray();

            // BigInteger q2 = 255;
            // var ba2 = q2.ToByteArray();

            // BigInteger q3 = 65535;
            // var ba3 = q3.ToByteArray();

            // BigInteger q4 = 8392705;
            // var ba4 = q4.ToByteArray();

            //// rand(new Random(), new BigInteger(new byte[]{2,0,0,0,0,0,0}));
            // Stopwatch sw = new Stopwatch();
            // var generator = new MersenneTwister();
            // q = 281474976711419;

            // long time = 0;
            // for (int i = 0; i < 100; i++)
            // {
            //     sw.Start();
            //     Console.WriteLine(AlgoAndMath.RandomBigInt(generator, q));
            //     sw.Stop();
            //     time += sw.ElapsedTicks;
            // }
            // Console.WriteLine("{0}\t{1}\t{2}\t{3}", time, time / 100, time / TimeSpan.TicksPerMillisecond, time / TimeSpan.TicksPerMillisecond / 100);

            //BigInteger p = 562949953422839;
            //var fl = AlgoAndMath.IsProbablePrime(p, 40);
            //var p1 = AlgoAndMath.NextPrime(p);
            //var p2 = AlgoAndMath.NextSafePrime(BigInteger.Pow(2, 128));

            //MainPaper.Execute();
            //var a = new BigInteger(986134576183746587);
            //var b = new BigInteger(9837458117549134571);
            //while ( BigInteger.GreatestCommonDivisor(a, b) > BigInteger.One)
            //{
            //    a = a / BigInteger.GreatestCommonDivisor(a, b);
            //}
            //var inv = AlgoAndMath.ModInverse(a, b);
        }

        static BigInteger rand(Random source, BigInteger bound)
        {
            var buffer = bound.ToByteArray();
            var n = buffer.Length;
            var msb = buffer[n - 1];
            var mask = 0;
            while (mask < msb)
                mask = (mask << 1) + 1;
            //while (true)
            //{
            //    source.NextBytes(buffer);
            //    buffer[n - 1] &= mask;
            //    var r = new BigInteger(buffer);
            //    if (r < bound)
            //        return r;
            //}
            return BigInteger.One;
        }
    }
}
